問題解説: VXLANつながらない
問題文
VXLANでの通信を検証するように依頼された。
異なるサーバ上のVXLANインターフェースがお互いに通信できるようにしてほしいとのことだ。サーバ同士はソフトウェアルータを介してL3の疎通性がある。VXLANのアンダーレイ通信には、マルチキャストルーティングを利用してほしいそうだ。
前任者も設定を行ったようなのだが、上手くいかずに諦めてしまったらしい。どうにか設定を変更して、VXLANインターフェース同士が通信できるようにしてほしい。
制約
VXLANインターフェース間の通信は、マルチキャストルーティングを用いたVXLAN通信でなければならない。
スタート地点
Server 1/2のVXLANインターフェース vxlan42
から Server 2/1のVXLANインターフェース vxlan42
へ ping
が通らない。
ゴール地点
Server 1/2のVXLANインターフェース vxlan42
から Server 2/1のVXLANインターフェース vxlan42
へ ping
が通る。
トラブルの概要
「VXLANが繋がらない」は、L2延伸技術であるVXLANを用います。VXLANは、パケットをカプセル化することでL3ネットワークを超えてL2ネットワークを構成します。
この問題のトポロジーは以下のようになっています。
2台のVMが異なるL2ネットワークに属しており、VyOSによってルーティングされます。それぞれのVMの中にはVXLAN用のインターフェースがあり、これらは仮想的に同じL2ネットワークにあります。
この図のvxlan42から出たパケットがens3でカプセル化され、もう一方のVMのens3を通ってvxlan42に届き、カプセル化が解除されます。
VMのens3とVyOSによって作られるL3ネットワークをアンダーレイ、vxlan42によって作られるL2ネットワークをオーバーレイと呼びます。
一般に、VXLANでは、アンダーレイでのブロードキャストをオーバーレイでのマルチキャストで実装します。ブロードキャストはARPに必要です。オーバーレイがL3ネットワークなので、マルチキャストルーティングを行う必要があります。
この問題では、vxlan42同士が通信できないというトラブルが起こっています。 .67
の方のVMで以下を実行しても疎通が取れません。
$ ping -I vxlan42 10.0.0.3
解説
この問題で起こっているトラブルには要因が2つあります。
– vxlan42 から送られるパケットの TTL が 1 になっている
– VyOS がマルチキャストルーティングを扱えない
TTLについては、VMのVXLANインターフェースが原因です。VXLANインターフェースにTTLを明示的に設定しない場合、TTLが1のパケットが送信されます。 TTLはルーティングの度にデクリメントされ、0になるとパケットが破棄されてしまいます。そこで、VXLANインターフェースの設定を変更する必要があります。
VXLANはマルチキャストルーティングを用いると述べました。実際には、マルチキャストを用いない例もあるのですが、この問題ではマルチキャストを使うよう制約を設けました。ところが、VyOSの config をどのように設定してもマルチキャストルーティングを行うことができません。そのような設定項目がないからです。この問題では VyOS 1.1.7 を使っていますが、私の知る限りは設定方法がありません。
VyOSがマルチキャストルーティングを行うことができないので、パケットが破棄されてしまいます。
しかし、VyOSはDebianをベースにしたソフトウェアルータなので、様々な外部のパッケージを導入することができます。これにより、マルチキャストルーティングを行うことができるようになります。
解答例
まずはVMのVXLANインターフェースのTTLを増やします。
今回、VMのOSはUbuntu 16.04です。はじめ、/etc/network/interfaces
に以下のようにVXLANインターフェースの設定が書いてあります。
auto vxlan42
iface vxlan42 inet manual
pre-up ip link add vxlan42 type vxlan id 42 group 239.255.255.255 || true
up ip address add 10.0.0.2/24 dev vxlan42 && ip link set vxlan42 up
down ip link set vxlan42 down
post-down ip link del vxlan42 || true
これを下記のように書き換えます。
auto vxlan42
iface vxlan42 inet manual
pre-up ip link add vxlan42 type vxlan id 42 group 239.255.255.255 ttl 2 || true
up ip address add 10.0.0.2/24 dev vxlan42 && ip link set vxlan42 up
down ip link set vxlan42 down
post-down ip link del vxlan42 || true
追加した項目は2行目の ttl 2
のみです。これで送信するパケットのTTLが設定されます。今回はルータを1台はさむ構成なので、TTLが2以上であれば良いです。
$ sudo service networking restart
以上のコマンドを実行すれば設定が反映されます。
続いて、VyOSがマルチキャストルーティングできるようにします。
これはあくまで一例ですが、以下のようにして、外部のリポジトリを登録します。
$ conf
$ set system package repository squeeze components 'main contrib non-free'
$ set system package repository squeeze distribution 'squeeze'
$ set system package repository squeeze url 'http://archive.debian.org/debian'
$ commit; save
ただし、このままでは以下のコマンドでのパッケージのアップデートに失敗します。
$ sudo aptitude update
これは、DNSサーバが設定されていないためです。
$ vi /etc/resolve.conf
nameserver 8.8.8.8
このように /etc/resolve.conf
などを修正すれば、アップデートが実行できるようになります。
そして、マルチキャストルーティングのプロトコルであるPIMを扱うために、PIMDをインストールします。
$ sudo aptitude install pimd
インストールすれば自動的にプロセスが立ち上がり、マルチキャストルーティングが動作するようになります。ただし、インストールしてから動作するまでは少し時間がかかります。
以上の項目を完了すれば、以下のコマンドで疎通が取れるはずです。
$ ping -I vxlan42 10.0.0.3
講評
この問題を完全に解くことができたのは1チームだけでした。
余談
ちなみに、この問題はICTSC 8の運営での経験から思いつきました。ICTSC 8ではVXLANを使うことで、Mと手元機材が同じL2ネットワークにあるように見せました。この際、アンダーレイはOpenStackとJuniper機器で構成しました。
OpenStack では以下の設定を変える必要がありました。
- VXLANインターフェースのTTL
- OpenStackの設定で変更することができます
- VXLANインターフェースのマルチキャストグループ
- デフォルトではリンクローカルの
224.0.0.0/4
になっているので別のものに変更する
- デフォルトではリンクローカルの
- VXLANのポート番号
- Juniperの機器はVXLANのポート番号として4789を使うのですが、Linuxのデフォルトは8742になっています
- Linuxのカーネルパラメータで変更することができます
これらの経験から、TTLの変更を問題にすることを思いつきました。また、VyOSでVXLANを行うにあたって、マルチキャストルーティングができなさそうなことが検証段階で分かったので、それもトラブルとして加えました。